// -----------------------------------------------------------------------
//  <copyright file="UpdateDictionaryTypeCommand.cs" company="LiuliuSoft">
//      Copyright (c) 2025 66SOFT. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2025-10-17 01:10</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Authorization;
using DaprPlus.Domain;
using DaprPlus.DataDicts.Domain.Dtos;
using DaprPlus.DataDicts.Domain.Entities;
using DaprPlus.DataDicts.Domain.Specs;
using DaprPlus.Domain.Entity;
using DaprPlus.Mapping;
using DaprPlus.MediatR;

using FluentValidation;


namespace DaprPlus.DataDicts.Application.Commands;

[AuthConfig(typeof(DictionaryType), ResourceAccessType.RoleLimit, "Update")]
public class UpdateDictionaryTypeCommand : IRequest<ApiResult>, ICommand
{
    public DictionaryTypeInDto[] Dtos { get; set; } = [];
}

public class UpdateDictionaryTypeCommandHandler(IServiceProvider provider)
    : IRequestHandler<UpdateDictionaryTypeCommand, ApiResult>
{
    public async Task<ApiResult> Handle(UpdateDictionaryTypeCommand request, CancellationToken cancellationToken)
    {
        var logger = provider.GetLogger<UpdateDictionaryTypeCommandHandler>();
        var repository = provider.GetRequiredService<IRepository<DictionaryType>>();
        var entities = new List<DictionaryType>();
        foreach (var dto in request.Dtos)
        {
            var entity = await repository.FindAsync(dto.Id, cancellationToken);
            if (entity == null)
            {
                logger.LogWarning("更新字典类型时编号为 {Id} 的字典类型不存在", dto.Id);
                return new ApiResult(ApiResultType.Error, $"编号为 {dto.Id} 的字典类型不存在");
            }
            entity = dto.MapTo(entity);
            entities.Add(entity);
        }
        await repository.UpdateAsync(entities.ToArray(), cancellationToken);

        logger.LogInformation("字典类型【{Names}】更新成功", entities.ExpandAndToString(m => m.Name));

        return new ApiResult(ApiResultType.Success, $"字典类型 {entities.ExpandAndToString(m => m.Name)} 更新成功");
    }
}

public class UpdateDictionaryTypeCommandValidator : AbstractValidator<UpdateDictionaryTypeCommand>
{
    public UpdateDictionaryTypeCommandValidator(IRepository<DictionaryType> repository)
    {
        RuleFor(x => x.Dtos)
            .NotEmpty()
            .WithMessage("字典类型数据不能为空")
            .Must(dtos =>
            {
                var codes = dtos.Select(x => x.Code).ToList();
                return codes.Count == codes.Distinct().Count();
            })
            .WithMessage("批量更新的字典类型中存在重复的代码");

        RuleForEach(x => x.Dtos).ChildRules(dto =>
        {
            dto.RuleFor(x => x.Id)
                .MustAsync(async (id, cancellationToken) =>
                {
                    var spec = new DictionaryTypeByIdSpec(id);
                    var flag = await repository.AnyAsync(spec, cancellationToken);
                    return flag;
                })
                .WithMessage((request, id) => $"编号为 {id} 的字典类型不存在");

            dto.RuleFor(x => x.Name)
                .NotEmpty()
                .MaximumLength(50)
                .WithMessage("字典类型名称不能为空且长度不能超过50个字符");

            dto.RuleFor(x => x.Code)
                .NotEmpty()
                .MaximumLength(50)
                .MustAsync(async (request, code, cancellationToken) =>
                {
                    var spec = new DictionaryTypeByCodeSpec(code).AndNot(new DictionaryTypeByIdSpec(request.Id));
                    var flag = await repository.AnyAsync(spec, cancellationToken);
                    return !flag;
                })
                .WithMessage((request, code) => $"代码为 {code} 的字典类型已存在");
        });
    }
}
